//
// Copyright 2007-2009 Taglab Limited.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package com.taglab.chic.mail;

import javax.mail.internet.MimeMessage;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.core.task.TaskExecutor;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSenderImpl;

/**
 * Extends {@link JavaMailSenderImpl} to send emails in a separate thread.
 * <p>
 * This is especially useful in web controllers, so that the user does not
 * have to wait for emails to be sent before receving a response.
 * <p>
 * Thread pooling can be provided by the pluggable {@link TaskExecutor}.
 * Sample Spring configuration:
 * <pre>
 * &lt;bean id="mailSender" class="com.taglab.chic.mail.AsyncJavaMailSender"&gt;
 *   &lt;property name="taskExecutor"&gt;
 *     &lt;bean class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"&gt;
 *       &lt;property name="corePoolSize" value="5"/&gt;
 *       &lt;property name="maxPoolSize" value="15"/&gt;
 *     &lt;/bean&gt;
 *   &lt;/property&gt;
 *   &lt;property name="host" value="mailhost"/&gt;
 *   &lt;property name="defaultEncoding" value="UTF-8"/&gt;
 * &lt;/bean&gt;
 * </pre>
 *
 * XXX Spring open's a connection every doSend call, could do with optimizing 
 */
public class AsyncJavaMailSender extends JavaMailSenderImpl {

  private class SendTask implements Runnable {

    private final MimeMessage[] mimeMessages;
    private final Object[] originalMessages;

    public SendTask(MimeMessage[] mimeMessages, Object[] originalMessages) {
      this.mimeMessages = mimeMessages;
      this.originalMessages = originalMessages;
    }

    public void run() {
      AsyncJavaMailSender.super.doSend(mimeMessages, originalMessages);
    }
  }

  private TaskExecutor taskExecutor;

  @Required
  public void setTaskExecutor(TaskExecutor taskExecutor) {
    this.taskExecutor = taskExecutor;
  }

  @Override
  protected void doSend(MimeMessage[] mimeMessages, Object[] originalMessages) throws MailException {
    taskExecutor.execute(new SendTask(mimeMessages, originalMessages));
  }

}
